/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package com.lineage.server.controller;

import java.util.Calendar;
import java.util.TimeZone;

import com.lineage.configure.Config;
import com.lineage.server.datatables.CastleTable;
import com.lineage.server.datatables.DoorTable;
import com.lineage.server.model.L1CastleLocation;
import com.lineage.server.model.L1Clan;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.L1Teleport;
import com.lineage.server.model.L1WarSpawn;
import com.lineage.server.model.L1World;
import com.lineage.server.model.Instance.L1CrownInstance;
import com.lineage.server.model.Instance.L1DoorInstance;
import com.lineage.server.model.Instance.L1FieldObjectInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.Instance.L1TowerInstance;
import com.lineage.server.packetserver.S_PacketBox;
import com.lineage.server.templates.L1Castle;

/**
 * 攻城战时间控制器.
 */
public final class WarTimeController implements Runnable {
    /** 实例. */
    private static WarTimeController instance;

    /** 参数. */
    private static final byte NUMBER = 8;

    /**
     * 实例为空时才新创建一个.
     * 
     * @return 实例
     */
    public static WarTimeController getInstance() {
        if (instance == null) {
            instance = new WarTimeController();
        }
        return instance;
    }

    /**
     * 取得现实时间.
     * 
     * @return 现实时间
     */
    private static Calendar getRealTime() {
        final TimeZone tz = TimeZone.getTimeZone(Config.TIME_ZONE);
        final Calendar cal = Calendar.getInstance(tz);
        return cal;
    }

    /** 城堡. */
    private final L1Castle[] castle = new L1Castle[NUMBER];

    /** 攻城战开始时间. */
    private final Calendar[] warStartTime = new Calendar[NUMBER];

    /** 攻城战结束时间. */
    private final Calendar[] warEndTime = new Calendar[NUMBER];

    /** 是否在攻城战中. */
    private final boolean[] isNowWar = new boolean[NUMBER];

    /**
     * 攻城战时间控制器.
     */
    private WarTimeController() {
        for (int i = 0; i < this.castle.length; i++) {
            this.castle[i] = CastleTable.getInstance().getCastleTable(i + 1);
            this.warStartTime[i] = this.castle[i].getWarTime();
            this.warEndTime[i] = (Calendar) this.castle[i].getWarTime().clone();
            this.warEndTime[i].add(Config.ALT_WAR_TIME_UNIT,
                    Config.ALT_WAR_TIME);
        }
    }

    /**
     * 检查当前是否有攻城战、如果有则发送信息(%s的攻城战正在进行中).
     * 
     * @param pc
     *            对象
     */
    public void checkCastleWar(final L1PcInstance pc) {
        for (int i = 0; i < NUMBER; i++) {
            if (this.isNowWar[i]) {
                final S_PacketBox msg = new S_PacketBox(
                        S_PacketBox.MSG_WAR_GOING, i + 1);
                pc.sendPackets(msg); // %s的攻城战正在进行中。
            }
        }
    }

    /**
     * 检查攻城时间.
     */
    private void checkWarTime() {
        for (int i = 0; i < NUMBER; i++) {
            if (this.warStartTime[i].before(getRealTime()) // 攻城开始
                    && this.warEndTime[i].after(getRealTime())) {
                if (!this.isNowWar[i]) {
                    this.isNowWar[i] = true;
                    // 招出攻城的旗子
                    final L1WarSpawn warspawn = new L1WarSpawn();
                    warspawn.SpawnFlag(i + 1);
                    // 修理城门并设定为关闭
                    for (final L1DoorInstance door : DoorTable.getInstance()
                            .getDoorList()) {
                        if (L1CastleLocation.checkInWarArea(i + 1, door)) {
                            door.repairGate();
                        }
                    }
                    final S_PacketBox msg = new S_PacketBox(
                            S_PacketBox.MSG_WAR_BEGIN, i + 1);
                    // %s的攻城战开始。
                    L1World.getInstance().broadcastPacketToAll(msg);
                    int[] loc = new int[3];
                    for (final L1PcInstance pc : L1World.getInstance()
                            .getAllPlayers()) {
                        final int castleId = i + 1;
                        if (L1CastleLocation.checkInWarArea(castleId, pc)
                                && !pc.isGm()) { // 刚好在攻城范围内
                            final L1Clan clan = L1World.getInstance().getClan(
                                    pc.getClanname());
                            if (clan != null) {
                                if (clan.getCastleId() == castleId) { // 如果是有城血盟
                                    continue;
                                }
                            }
                            loc = L1CastleLocation.getGetBackLoc(castleId);
                            final int head = 5; // 面向
                            L1Teleport.teleport(pc, loc[0], loc[1], loc[2],
                                    head, true);
                        }
                    }
                }
            } else // 攻城结束
            if (this.warEndTime[i].before(getRealTime())) {
                if (this.isNowWar[i]) {
                    this.isNowWar[i] = false;
                    final S_PacketBox msg = new S_PacketBox(
                            S_PacketBox.MSG_WAR_END, i + 1);
                    // %s的攻城战结束。
                    L1World.getInstance().broadcastPacketToAll(msg);
                    // 更新攻城时间
                    this.warUpdate(i);

                    final int castleId = i + 1;
                    for (final L1Object l1object : L1World.getInstance()
                            .getObject()) {
                        // 取消攻城的旗子
                        if (l1object instanceof L1FieldObjectInstance) {
                            final L1FieldObjectInstance flag = (L1FieldObjectInstance) l1object;
                            if (L1CastleLocation.checkInWarArea(castleId, flag)) {
                                flag.deleteMe();
                            }
                        }
                        // 移除皇冠
                        if (l1object instanceof L1CrownInstance) {
                            final L1CrownInstance crown = (L1CrownInstance) l1object;
                            if (L1CastleLocation
                                    .checkInWarArea(castleId, crown)) {
                                crown.deleteMe();
                            }
                        }
                        // 移除守护塔
                        if (l1object instanceof L1TowerInstance) {
                            final L1TowerInstance tower = (L1TowerInstance) l1object;
                            if (L1CastleLocation
                                    .checkInWarArea(castleId, tower)) {
                                tower.deleteMe();
                            }
                        }
                    }
                    // 塔重新出现
                    final L1WarSpawn warspawn = new L1WarSpawn();
                    warspawn.SpawnTower(castleId);

                    // 移除城门
                    for (final L1DoorInstance door : DoorTable.getInstance()
                            .getDoorList()) {
                        if (L1CastleLocation.checkInWarArea(castleId, door)) {
                            door.repairGate();
                        }
                    }
                } else { // 更新过期的攻城时间
                    this.warStartTime[i] = getRealTime();
                    this.warEndTime[i] = (Calendar) this.warStartTime[i]
                            .clone();
                    this.warUpdate(i);
                }
            }

        }
    }

    /**
     * 检查城堡是否攻城战区域.
     * 
     * @param castleId
     *            城堡编号
     * @return 城堡编号
     */
    public boolean isNowWar(final int castleId) {
        return this.isNowWar[castleId - 1];
    }

    @Override
    public void run() {
        try {
            while (true) {
                this.checkWarTime(); // 检查攻城时间
                final int time = 1000; // 1秒(休眠时间)
                Thread.sleep(time);
            }
        } catch (final Exception e1) {
        }
    }

    /**
     * 更新攻城战时间.
     * 
     * @param i
     *            参数
     */
    private void warUpdate(final int i) {
        this.warStartTime[i].add(Config.ALT_WAR_INTERVAL_UNIT,
                Config.ALT_WAR_INTERVAL);
        this.warEndTime[i].add(Config.ALT_WAR_INTERVAL_UNIT,
                Config.ALT_WAR_INTERVAL);
        this.castle[i].setWarTime(this.warStartTime[i]);
        this.castle[i].setTaxRate(10); // 税率10%
        this.castle[i].setPublicMoney(0); // 清除城堡税收
        CastleTable.getInstance().updateCastle(this.castle[i]);
    }
}
